home *** CD-ROM | disk | FTP | other *** search
/ Revista do CD-ROM 97 / CD-ROM 97 / CD-ROM 97.iso / internet / ghostzilla / ghsetup.exe / chrome / toolkit.jar / content / global / bindings / tree.xml < prev    next >
Encoding:
Extensible Markup Language  |  2002-05-03  |  34.0 KB  |  993 lines

  1. <?xml version="1.0"?>
  2.  
  3. <bindings id="treeBindings"
  4.    xmlns="http://www.mozilla.org/xbl"
  5.    xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
  6.    xmlns:xbl="http://www.mozilla.org/xbl">
  7.   
  8.   <binding id="tree-base">
  9.     <resources>
  10.       <stylesheet src="chrome://global/skin/tree.css"/>
  11.     </resources>
  12.   </binding>
  13.  
  14.   <binding id="tree" extends="chrome://global/content/bindings/tree.xml#tree-base">
  15.     <content>
  16.       <children includes="treecols"/>
  17.       <xul:treerows class="tree-rows" flex="1">
  18.         <children/>
  19.       </xul:treerows>
  20.     </content>
  21.     
  22.     <implementation>
  23.       <constructor>
  24.         this.addEventListener("DOMMouseScroll", this._handleMouseScroll, true);
  25.         if (navigator.platform.indexOf("Mac") != -1)
  26.           this.pageUpOrDownMovesSelection = false;
  27.       </constructor>
  28.  
  29.       <property name="treeBoxObject"
  30.                 onget="return this.boxObject.QueryInterface(Components.interfaces.nsITreeBoxObject);"
  31.                 readonly="true"/>
  32.       <property name="view"
  33.                 onget="return this.treeBoxObject.view;"
  34.                 onset="return this.treeBoxObject.view=val;"/>
  35.       <property name="contentView"
  36.                 onget="return this.view.QueryInterface(Components.interfaces.nsITreeContentView);"
  37.                 readonly="true"/>
  38.       <property name="builderView"
  39.                 onget="return this.view.QueryInterface(Components.interfaces.nsIXULTreeBuilder);"
  40.                 readonly="true"/>
  41.       <property name="currentIndex"
  42.                 onget="return this.treeBoxObject.selection.currentIndex;"
  43.                 onset="return this.treeBoxObject.selection.currentIndex=val;"/>
  44.       <field name="pageUpOrDownMovesSelection">
  45.         true
  46.       </field>
  47.       <field name="selectionHead">
  48.         -1
  49.       </field>
  50.       <field name="selectionTail">
  51.         -1
  52.       </field>
  53.       <property name="singleSelection"
  54.                 onget="return this.getAttribute('seltype') == 'single'"
  55.                 readonly="true"/>
  56.  
  57.       <property name="enableColumnDrag"
  58.                 onget="return this.hasAttribute('enableColumnDrag');"
  59.                 onset="if (val) this.setAttribute('enableColumnDrag', 'true');
  60.                        else this.removeAttribute('enableColumnDrag'); return val;"/>
  61.  
  62.       <property name="firstOrdinalColumn">
  63.         <getter><![CDATA[
  64.           var cols = this.firstChild;
  65.           while (cols && cols.localName != "treecols")
  66.             cols = cols.nextSibling;
  67.  
  68.           if (cols)
  69.             return cols.boxObject.firstChild;
  70.           else
  71.             return null;
  72.         ]]></getter>
  73.       </property>
  74.       
  75.       <field name="_columnsDirty">true</field>
  76.  
  77.       <field name="_handleMouseScroll">
  78.       <![CDATA[
  79.         ({
  80.           subject: this,
  81.           handleEvent: function(aEvent)
  82.           {
  83.             var rows = aEvent.detail;
  84.             if (rows == NSUIEvent.SCROLL_PAGE_UP)
  85.               this.subject.treeBoxObject.scrollByPages(-1);
  86.             else if (rows == NSUIEvent.SCROLL_PAGE_DOWN)
  87.               this.subject.treeBoxObject.scrollByPages(1);
  88.             else
  89.               this.subject.treeBoxObject.scrollByLines(aEvent.detail);
  90.           }
  91.         })
  92.       ]]>
  93.       </field>
  94.  
  95.       <method name="_ensureColumnOrder">
  96.         <body><![CDATA[
  97.           if (this._columnsDirty) {
  98.             // update the ordinal position of each column to assure that it is
  99.             // an odd number and 2 positions above it's next sibling
  100.             var col = this.firstOrdinalColumn;
  101.             var cols = [];
  102.             while (col) {
  103.               if (col.localName == "treecol" && col.parentNode.parentNode == this)
  104.                 cols[cols.length] = col;
  105.               col = col.boxObject.nextSibling;
  106.             }
  107.             var i;
  108.             for (i = 0; i < cols.length; ++i)
  109.               cols[i].setAttribute("ordinal", (i*2)+1);
  110.               
  111.             // update the ordinal positions of splitters to even numbers, so that 
  112.             // they are in between columns
  113.             var splitters = this.getElementsByTagName("splitter");
  114.             for (i = 0; i < splitters.length; ++i)
  115.               splitters[i].setAttribute("ordinal", (i+1)*2);
  116.             
  117.             this._columnsDirty = false;
  118.           }
  119.         ]]></body>
  120.       </method>
  121.  
  122.       <method name="_reorderColumn">
  123.         <parameter name="aColMove"/>
  124.         <parameter name="aColBefore"/>
  125.         <parameter name="aBefore"/>
  126.         <body><![CDATA[
  127.           this._ensureColumnOrder();
  128.           
  129.           var cols = [];
  130.           var col;
  131.           if (aColBefore.ordinal < aColMove.ordinal) {
  132.             col = aColBefore;
  133.             while (col) {
  134.               if (col.localName == "treecol")
  135.                 cols.push(col);
  136.               col = col.boxObject.nextSibling;
  137.               if (col == aColMove)  
  138.                 break;
  139.             }
  140.  
  141.             aColMove.ordinal = aColBefore.ordinal;
  142.             var i;
  143.             for (i = 0; i < cols.length; ++i)
  144.               cols[i].ordinal += 2;
  145.           } else {
  146.             col = aColMove.boxObject.nextSibling;
  147.             while (col) {
  148.               if (col.localName == "treecol")
  149.                 cols.push(col);
  150.               col = col.boxObject.nextSibling;
  151.               if (col == aColBefore && aBefore)
  152.                 break;
  153.             }
  154.  
  155.             aColMove.ordinal = aBefore ? aColBefore.ordinal-2 : aColBefore.ordinal;
  156.  
  157.             for (i = 0; i < cols.length; ++i)
  158.               cols[i].ordinal -= 2;
  159.           }
  160.         ]]></body>
  161.       </method>
  162.       
  163.       <method name="_getColumnAtX">
  164.         <parameter name="aX"/>
  165.         <parameter name="aThresh"/>
  166.         <parameter name="aPos"/>
  167.         <body><![CDATA[
  168.           if (aPos) aPos.value = "before";
  169.  
  170.           var col = this.firstOrdinalColumn;
  171.           var lastCol = null;
  172.           var currentX = this.boxObject.x;
  173.           while (col) {
  174.             if (col.localName == "treecol" && col.parentNode.parentNode == this) {
  175.               var cw = col.boxObject.width;
  176.               if (cw > 0) {
  177.                 currentX += cw;
  178.                 if (currentX - (cw*aThresh) > aX)
  179.                   return col;
  180.               }
  181.               lastCol = col;
  182.             }
  183.             col = col.boxObject.nextSibling;
  184.           }
  185.  
  186.           if (aPos) aPos.value = "after";
  187.           return lastCol;
  188.         ]]></body>
  189.       </method>
  190.  
  191.     </implementation>
  192.     
  193.     <handlers>
  194.       <handler event="focus" action="this.treeBoxObject.focused = true;"/>
  195.       <handler event="blur" action="this.treeBoxObject.focused = false;"/>
  196.   
  197.       <handler event="dragenter" action="this.treeBoxObject.onDragEnter(event);"/>
  198.       <handler event="dragexit" action="this.treeBoxObject.onDragExit(event);"/>
  199.       <handler event="dragover" action="this.treeBoxObject.onDragOver(event);"/>
  200.       <handler event="dragdrop" action="this.treeBoxObject.onDragDrop(event);"/>
  201.  
  202.       <handler event="keypress" keycode="vk_enter">
  203.         <![CDATA[
  204.          if (this.currentIndex == -1)
  205.            return;
  206.          if (this.treeBoxObject.view.isContainer(this.currentIndex))
  207.            this.treeBoxObject.view.toggleOpenState(this.currentIndex);
  208.         ]]>
  209.       </handler>
  210.       <handler event="keypress" keycode="vk_return">
  211.         <![CDATA[
  212.          if (this.currentIndex == -1)
  213.            return;
  214.          if (this.treeBoxObject.view.isContainer(this.currentIndex))
  215.            this.treeBoxObject.view.toggleOpenState(this.currentIndex);
  216.         ]]>
  217.       </handler>
  218.       <handler event="keypress" keycode="vk_left">
  219.         <![CDATA[
  220.          if (this.currentIndex == -1)
  221.            return;
  222.          if (this.treeBoxObject.view.isContainer(this.currentIndex) &&
  223.              this.treeBoxObject.view.isContainerOpen(this.currentIndex)) {
  224.            this.treeBoxObject.view.toggleOpenState(this.currentIndex);
  225.          }
  226.          else {
  227.            var parentIndex = this.treeBoxObject.view.getParentIndex(this.currentIndex);
  228.            if (parentIndex >= 0)
  229.              this.treeBoxObject.selection.select(parentIndex);
  230.          }
  231.         ]]>
  232.       </handler>
  233.       <handler event="keypress" keycode="vk_right">
  234.         <![CDATA[
  235.          if (this.currentIndex == -1)
  236.            return;
  237.          if (this.treeBoxObject.view.isContainer(this.currentIndex)) {
  238.            if (!this.treeBoxObject.view.isContainerOpen(this.currentIndex))
  239.              this.treeBoxObject.view.toggleOpenState(this.currentIndex);
  240.          }
  241.         ]]>
  242.       </handler>
  243.       <handler event="keypress" keycode="vk_up">
  244.         <![CDATA[
  245.          var c = this.currentIndex;
  246.          if (c == -1 || c == 0)
  247.            return;
  248.          this.selectionHead = -1;
  249.          this.selectionTail = -1;
  250.          this.treeBoxObject.selection.timedSelect(c-1, 500);
  251.          this.treeBoxObject.ensureRowIsVisible(c-1);
  252.         ]]>
  253.       </handler>
  254.       <handler event="keypress" keycode="vk_down">
  255.         <![CDATA[
  256.          var c = this.currentIndex;
  257.          try { if (c+1 == this.treeBoxObject.view.rowCount)
  258.            return;
  259.          } catch (e) {}
  260.          this.selectionHead = -1;
  261.          this.selectionTail = -1;
  262.          this.treeBoxObject.selection.timedSelect(c+1, 500);
  263.          this.treeBoxObject.ensureRowIsVisible(c+1);
  264.         ]]>
  265.       </handler>
  266.       <handler event="keypress" keycode="vk_up" modifiers="shift">
  267.         <![CDATA[
  268.          if (this.singleSelection)
  269.            return;
  270.          var c = this.currentIndex;
  271.          if (c == -1 || c == 0)
  272.            return;
  273.          if (c == this.selectionTail) {
  274.            if (this.selectionHead < this.selectionTail) {
  275.              this.treeBoxObject.selection.toggleSelect(c);
  276.              this.currentIndex = c - 1;
  277.            }
  278.            else {
  279.              this.treeBoxObject.selection.toggleSelect(c - 1);
  280.            }
  281.          }
  282.          else {
  283.            this.treeBoxObject.selection.clearSelection();
  284.            this.selectionHead = c;
  285.            this.treeBoxObject.selection.rangedSelect(c, c - 1, true);
  286.          }
  287.          this.selectionTail = c - 1;
  288.          this.treeBoxObject.ensureRowIsVisible(c - 1);
  289.         ]]>
  290.       </handler>
  291.       <handler event="keypress" keycode="vk_down" modifiers="shift">
  292.         <![CDATA[
  293.          if (this.singleSelection)
  294.            return;
  295.          var c = this.currentIndex;
  296.          try { if (c+1 == this.treeBoxObject.view.rowCount)
  297.            return;
  298.          } catch (e) {}
  299.          if (c == this.selectionTail) {
  300.            if (this.selectionHead > this.selectionTail) {
  301.              this.treeBoxObject.selection.toggleSelect(c);
  302.              this.currentIndex = c + 1;
  303.            }
  304.            else
  305.              this.treeBoxObject.selection.toggleSelect(c + 1);
  306.          }
  307.          else {
  308.            this.treeBoxObject.selection.clearSelection();
  309.            this.selectionHead = c;
  310.            this.treeBoxObject.selection.rangedSelect(c, c + 1, true);
  311.          }
  312.          this.selectionTail = c + 1;
  313.          this.treeBoxObject.ensureRowIsVisible(c + 1);
  314.         ]]>
  315.       </handler>
  316.       <handler event="keypress" keycode="vk_up" modifiers="control">
  317.         <![CDATA[
  318.          var c = this.currentIndex;
  319.          if (c == -1 || c == 0)
  320.            return;
  321.          this.currentIndex = c-1;
  322.          this.treeBoxObject.ensureRowIsVisible(c-1);
  323.         ]]>
  324.       </handler>
  325.       <handler event="keypress" keycode="vk_down" modifiers="control">
  326.         <![CDATA[
  327.          var c = this.currentIndex;
  328.          try { if (c+1 == this.treeBoxObject.view.rowCount)
  329.            return;
  330.          } catch (e) {}
  331.          this.currentIndex = c+1;
  332.          this.treeBoxObject.ensureRowIsVisible(c+1);
  333.         ]]>
  334.       </handler>
  335.       <handler event="keypress" keycode="vk_page_up">
  336.         <![CDATA[
  337.          if (! this.pageUpOrDownMovesSelection) {
  338.            this.treeBoxObject.scrollByPages(-1);
  339.            return;
  340.          }
  341.          var c = this.currentIndex;
  342.          if (c == 0)
  343.            return;
  344.          this.selectionHead = -1;
  345.          this.selectionTail = -1;
  346.          var f = this.treeBoxObject.getFirstVisibleRow();
  347.          var i = 0;
  348.          if (f > 0) {
  349.            var p = this.treeBoxObject.getPageCount();
  350.            if (f - p >= 0)
  351.              i = c - p;
  352.            else
  353.              i = c - f;
  354.            this.treeBoxObject.scrollByPages(-1);
  355.          }
  356.          this.treeBoxObject.selection.timedSelect(i, 500);
  357.         ]]>
  358.       </handler>
  359.       <handler event="keypress" keycode="vk_page_down">
  360.         <![CDATA[
  361.          if (! this.pageUpOrDownMovesSelection) {
  362.            this.treeBoxObject.scrollByPages(1);
  363.            return;
  364.          }
  365.          var c = this.currentIndex;
  366.          var l = this.treeBoxObject.view.rowCount - 1;
  367.          if (c == l)
  368.            return;
  369.          this.selectionHead = -1;
  370.          this.selectionTail = -1;
  371.          var f = this.treeBoxObject.getFirstVisibleRow();
  372.          var p = this.treeBoxObject.getPageCount();
  373.          var i = l;
  374.          var lastTopRowIndex = l - p;
  375.          if (f <= lastTopRowIndex) {
  376.            if (f + p <= lastTopRowIndex)
  377.              i = c + p;
  378.            else
  379.              i = lastTopRowIndex + c - f + 1;
  380.            this.treeBoxObject.scrollByPages(1);
  381.          }
  382.          this.treeBoxObject.selection.timedSelect(i, 500);
  383.         ]]>
  384.       </handler>
  385.       <handler event="keypress" keycode="vk_page_up" modifiers="shift">
  386.         <![CDATA[
  387.          if (this.singleSelection)
  388.            return;
  389.          var c = this.currentIndex;
  390.          if (c == 0)
  391.            return;
  392.          var f = this.treeBoxObject.getFirstVisibleRow();
  393.          var i = 0;
  394.          if (f > 0) {
  395.            var p = this.treeBoxObject.getPageCount();
  396.            if (f - p >= 0)
  397.              i = c - p;
  398.            else
  399.              i = c - f;
  400.            this.treeBoxObject.scrollByPages(-1);
  401.          }
  402.          if (c == this.selectionTail) {
  403.            if (this.selectionHead < this.selectionTail) {
  404.              if (i < this.selectionHead) {
  405.                this.treeBoxObject.selection.clearRange(c, this.selectionHead + 1);
  406.                this.treeBoxObject.selection.rangedSelect(this.selectionHead - 1, i, true);
  407.              }
  408.              else {
  409.                this.treeBoxObject.selection.clearRange(c, i + 1);
  410.                this.currentIndex = i;
  411.              }
  412.            }
  413.            else
  414.              this.treeBoxObject.selection.rangedSelect(c - 1, i, true);
  415.          }
  416.          else {
  417.            this.treeBoxObject.selection.clearSelection();
  418.            this.selectionHead = c;
  419.            this.treeBoxObject.selection.rangedSelect(c, i, true);
  420.          }
  421.          this.selectionTail = i;
  422.         ]]>
  423.       </handler>
  424.       <handler event="keypress" keycode="vk_page_down" modifiers="shift">
  425.         <![CDATA[
  426.          if (this.singleSelection)
  427.            return;
  428.          var c = this.currentIndex;
  429.          var l = this.treeBoxObject.view.rowCount - 1;
  430.          if (c == l)
  431.            return;
  432.          var f = this.treeBoxObject.getFirstVisibleRow();
  433.          var p = this.treeBoxObject.getPageCount();
  434.          var i = l;
  435.          var lastTopRowIndex = l - p;
  436.          if (f <= lastTopRowIndex) {
  437.            if (f + p <= lastTopRowIndex)
  438.              i = c + p;
  439.            else
  440.              i = lastTopRowIndex + c - f + 1;
  441.            this.treeBoxObject.scrollByPages(1);
  442.          }
  443.          if (c == this.selectionTail) {
  444.            if (this.selectionHead > this.selectionTail) {
  445.              if (i > this.selectionHead) {
  446.                this.treeBoxObject.selection.clearRange(c, this.selectionHead - 1);
  447.                this.treeBoxObject.selection.rangedSelect(this.selectionHead + 1, i, true);
  448.              }
  449.              else {
  450.                this.treeBoxObject.selection.clearRange(c, i - 1);
  451.                this.currentIndex = i;
  452.              }
  453.            }
  454.            else
  455.              this.treeBoxObject.selection.rangedSelect(c + 1, i, true);
  456.          }
  457.          else {
  458.            this.treeBoxObject.selection.clearSelection();
  459.            this.selectionHead = c;
  460.            this.treeBoxObject.selection.rangedSelect(c, i, true);
  461.          }
  462.          this.selectionTail = i;
  463.         ]]>
  464.       </handler>
  465.       <handler event="keypress" keycode="vk_page_up" modifiers="control">
  466.         <![CDATA[
  467.          var c = this.currentIndex;
  468.          if (c == 0)
  469.            return;
  470.          var f = this.treeBoxObject.getFirstVisibleRow();
  471.          var i = 0;
  472.          if (f > 0) {
  473.            var p = this.treeBoxObject.getPageCount();
  474.            if (f - p >= 0)
  475.              i = c - p;
  476.            else
  477.              i = c - f;
  478.            this.treeBoxObject.scrollByPages(-1);
  479.          }
  480.          this.currentIndex = i;
  481.         ]]>
  482.       </handler>
  483.       <handler event="keypress" keycode="vk_page_down" modifiers="control">
  484.         <![CDATA[
  485.          var c = this.currentIndex;
  486.          var l = this.treeBoxObject.view.rowCount - 1;
  487.          if (c == l)
  488.            return;
  489.          var f = this.treeBoxObject.getFirstVisibleRow();
  490.          var p = this.treeBoxObject.getPageCount();
  491.          var i = l;
  492.          var lastTopRowIndex = l - p;
  493.          if (f <= lastTopRowIndex) {
  494.            if (f + p <= lastTopRowIndex)
  495.              i = c + p;
  496.            else
  497.              i = lastTopRowIndex + c - f + 1;
  498.            this.treeBoxObject.scrollByPages(1);
  499.          }
  500.          this.currentIndex = i;
  501.         ]]>
  502.       </handler>
  503.       <handler event="keypress" keycode="vk_home">
  504.         <![CDATA[
  505.          if (this.currentIndex == 0)
  506.            return;
  507.          this.selectionHead = -1;
  508.          this.selectionTail = -1;
  509.          this.treeBoxObject.selection.timedSelect(0, 500);
  510.          this.treeBoxObject.ensureRowIsVisible(0);
  511.         ]]>
  512.       </handler>
  513.       <handler event="keypress" keycode="vk_end">
  514.         <![CDATA[
  515.          var l = this.treeBoxObject.view.rowCount - 1;
  516.          if (this.currentIndex == l)
  517.            return;
  518.          this.selectionHead = -1;
  519.          this.selectionTail = -1;
  520.          this.treeBoxObject.selection.timedSelect(l, 500);
  521.          this.treeBoxObject.ensureRowIsVisible(l);
  522.         ]]>
  523.       </handler>
  524.       <handler event="keypress" keycode="vk_home" modifiers="shift">
  525.         <![CDATA[
  526.          if (this.singleSelection)
  527.            return;
  528.          var c = this.currentIndex;
  529.          if (c == 0)
  530.            return;
  531.          if (c != this.selectionTail) {
  532.            this.treeBoxObject.selection.clearSelection();
  533.            this.selectionHead = c;
  534.          }
  535.          this.treeBoxObject.selection.rangedSelect(c, 0, true);
  536.          this.selectionTail = 0;
  537.          this.treeBoxObject.ensureRowIsVisible(0);
  538.         ]]>
  539.       </handler>
  540.       <handler event="keypress" keycode="vk_end" modifiers="shift">
  541.         <![CDATA[
  542.          if (this.singleSelection)
  543.            return;
  544.          var c = this.currentIndex;
  545.          var l = this.treeBoxObject.view.rowCount - 1;
  546.          if (c == l)
  547.            return;
  548.          if (c != this.selectionTail) {
  549.            this.treeBoxObject.selection.clearSelection();
  550.            this.selectionHead = c;
  551.          }
  552.          this.treeBoxObject.selection.rangedSelect(c, l, true);
  553.          this.selectionTail = l;
  554.          this.treeBoxObject.ensureRowIsVisible(l);
  555.         ]]>
  556.       </handler>
  557.       <handler event="keypress" keycode="vk_home" modifiers="control">
  558.         <![CDATA[
  559.          if (this.currentIndex == 0)
  560.            return;
  561.          this.currentIndex = 0;
  562.          this.treeBoxObject.ensureRowIsVisible(0);
  563.         ]]>
  564.       </handler>
  565.       <handler event="keypress" keycode="vk_end" modifiers="control">
  566.         <![CDATA[
  567.          var l = this.treeBoxObject.view.rowCount - 1;
  568.          if (this.currentIndex == l)
  569.            return;
  570.          this.currentIndex = l;
  571.          this.treeBoxObject.ensureRowIsVisible(l);
  572.         ]]>
  573.       </handler>
  574.       <handler event="keypress">
  575.         <![CDATA[
  576.          if (event.keyCode == ' '.charCodeAt(0)) {
  577.            var c = this.currentIndex;
  578.            if (!this.treeBoxObject.selection.isSelected(c))
  579.              this.treeBoxObject.selection.toggleSelect(c);
  580.          }
  581.          ]]>
  582.       </handler>
  583.     </handlers>    
  584.   </binding>
  585.  
  586.   <binding id="treecols" extends="chrome://global/content/bindings/tree.xml#tree-base">
  587.     <content>
  588.       <children includes="treecol|splitter"/>
  589.       <xul:treecolpicker class="treecol-image" fixed="true" ordinal="2147483647"/>
  590.     </content>
  591.   </binding>
  592.  
  593.   <binding id="treerows" extends="chrome://global/content/bindings/tree.xml#tree-base">
  594.     <content>
  595.       <xul:hbox flex="1" class="tree-bodybox">
  596.         <children/>
  597.       </xul:hbox>
  598.       <xul:scrollbar height="0" minwidth="0" minheight="0" orient="vertical" class="tree-scrollbar" collapsed="true"/>
  599.     </content>
  600.     <handlers>
  601.       <handler event="underflow">
  602.         <![CDATA[
  603.           document.getAnonymousNodes(this)[1].collapsed = true;
  604.           event.preventBubble();
  605.         ]]>
  606.       </handler>
  607.       <handler event="overflow">
  608.         <![CDATA[
  609.           document.getAnonymousNodes(this)[1].collapsed = false;
  610.           event.preventBubble();
  611.         ]]>
  612.       </handler>
  613.     </handlers>
  614.   </binding>
  615.  
  616.   <binding id="treebody" extends="chrome://global/content/bindings/tree.xml#tree-base">
  617.     <implementation>
  618.       <constructor>
  619.         if ("_ensureColumnOrder" in this.parentNode)
  620.           this.parentNode._ensureColumnOrder();
  621.       </constructor>
  622.  
  623.       <field name="_lastSelectedRow">
  624.         -1
  625.       </field>
  626.     </implementation>
  627.     <handlers>
  628.       <!-- If there is no modifier key, we select on mousedown, not
  629.            click, so that drags work correctly. -->
  630.       <handler event="mousedown">
  631.       <![CDATA[
  632.          if ((!event.ctrlKey && !event.shiftKey && !event.metaKey) ||
  633.              this.parentNode.singleSelection) {
  634.            var row = {};
  635.            var col = {};
  636.            var obj = {};
  637.            var b = this.parentNode.treeBoxObject;
  638.            b.getCellAt(event.clientX, event.clientY, row, col, obj);
  639.  
  640.            // save off the last selected row
  641.            this._lastSelectedRow = row.value;
  642.  
  643.            if (row.value == -1)
  644.              return;
  645.  
  646.            if (obj.value != "twisty") {
  647.              var column = document.getElementById(col.value);
  648.              var cycler = column.hasAttribute('cycler');
  649.  
  650.              if (cycler)
  651.                b.view.cycleCell(row.value, col.value);
  652.              else
  653.                  if (!b.selection.isSelected(row.value)) {
  654.                  b.selection.select(row.value);
  655.                  b.ensureRowIsVisible(row.value);
  656.                }
  657.            }
  658.          }
  659.       ]]>
  660.       </handler>
  661.  
  662.       <!-- On a click (up+down on the same item), deselect everything
  663.            except this item. -->
  664.       <handler event="click">
  665.       <![CDATA[
  666.         if (event.button != 0) return;
  667.         var row = {};
  668.         var col = {};
  669.         var obj = {};
  670.         var b = this.parentNode.treeBoxObject;
  671.         b.getCellAt(event.clientX, event.clientY, row, col, obj);
  672.  
  673.         if (row.value == -1)
  674.           return;
  675.  
  676.         if (obj.value == "twisty") {
  677.           if (b.selection.currentIndex >= 0 &&
  678.               b.view.isContainerOpen(row.value)) {
  679.             var parentIndex = b.view.getParentIndex(b.selection.currentIndex);
  680.             while (parentIndex >= 0 && parentIndex != row.value)
  681.               parentIndex = b.view.getParentIndex(parentIndex);
  682.             if (parentIndex == row.value)
  683.               b.selection.select(parentIndex);
  684.           }
  685.           b.view.toggleOpenState(row.value);
  686.           return;
  687.         }
  688.  
  689.         if (! this.parentNode.singleSelection) {
  690.           var augment = event.ctrlKey || event.metaKey;
  691.           if (event.shiftKey) {
  692.             b.selection.rangedSelect(-1, row.value, augment);
  693.             b.ensureRowIsVisible(row.value);
  694.             return;
  695.           }
  696.           if (augment) {
  697.             b.selection.toggleSelect(row.value);
  698.             b.ensureRowIsVisible(row.value);
  699.             b.selection.currentIndex = row.value;
  700.             return;
  701.           }
  702.         }
  703.  
  704.         /* We want to deselect all the selected items except what was
  705.           clicked, UNLESS it was a right-click.  We have to do this
  706.           in click rather than mousedown so that you can drag a
  707.           selected group of items */
  708.  
  709.         if (!col.value) return;
  710.         var column = document.getElementById(col.value);
  711.         var cycler = column.hasAttribute('cycler');
  712.  
  713.         // if the last row has changed in between the time we 
  714.         // mousedown and the time we click, don't fire the select handler.
  715.         // see bug #92366
  716.         if (!cycler && this._lastSelectedRow == row.value) {
  717.           b.selection.select(row.value);  
  718.           b.ensureRowIsVisible(row.value);
  719.         }
  720.       ]]>
  721.       </handler>
  722.  
  723.       <!-- double-click -->
  724.       <handler event="click" clickcount="2">
  725.       <![CDATA[
  726.            var row = {};
  727.            var col = {};
  728.            var obj = {};
  729.            var b = this.parentNode.treeBoxObject;
  730.            b.getCellAt(event.clientX, event.clientY, row, col, obj);
  731.  
  732.            if (row.value == -1)
  733.              return;
  734.  
  735.            var column = document.getElementById(col.value);
  736.            var cycler = column.hasAttribute('cycler');
  737.  
  738.            if (!cycler && obj.value != "twisty" && b.view.isContainer(row.value))
  739.              b.view.toggleOpenState(row.value);
  740.       ]]>
  741.       </handler>
  742.       
  743.     </handlers>
  744.   </binding>
  745.  
  746.   <binding id="treecol-base" extends="chrome://global/content/bindings/tree.xml#tree-base">
  747.     <implementation>
  748.       <constructor>
  749.         this.parentNode.parentNode._columnsDirty = true;
  750.       </constructor>
  751.  
  752.       <property name="ordinal">
  753.         <getter><![CDATA[
  754.           var val = this.getAttribute("ordinal");
  755.           return val == "" ? 1 : (val == "0" ? 0 : parseInt(val));
  756.         ]]></getter>
  757.         <setter><![CDATA[
  758.           this.setAttribute("ordinal", val);
  759.         ]]></setter>
  760.       </property>
  761.       
  762.       <property name="_previousVisibleColumn">
  763.         <getter><![CDATA[
  764.           var sib = this.boxObject.previousSibling;
  765.           while (sib) {
  766.             if (sib.localName == "treecol" && sib.boxObject.width > 0 && sib.parentNode == this.parentNode)
  767.               return sib;
  768.             sib = sib.boxObject.previousSibling;
  769.           }
  770.           return null;
  771.         ]]></getter>
  772.       </property>
  773.  
  774.       <method name="onDragMouseMove">
  775.         <parameter name="aEvent"/>
  776.         <body><![CDATA[
  777.           var col = document.treecolDragging;
  778.           if (!col) return;
  779.  
  780.           // determine if we have moved the mouse far enough
  781.           // to initiate a drag
  782.           if (col.mDragGesturing) {
  783.             if (Math.abs(aEvent.clientX - col.mStartDragX) < 5 &&
  784.                 Math.abs(aEvent.clientY - col.mStartDragY) < 5) {
  785.               return;
  786.             } else {
  787.               col.mDragGesturing = false;
  788.               col.setAttribute("dragging", "true");
  789.               window.addEventListener("click", col.onDragMouseClick, true);
  790.             }
  791.           }
  792.                     
  793.           var pos = {};
  794.           var targetCol = col.parentNode.parentNode._getColumnAtX(aEvent.clientX, 0.5, pos);
  795.           
  796.           // bail if we haven't mousemoved to a different column
  797.           if (col.mTargetCol == targetCol && col.mTargetDir == pos.value)
  798.             return;
  799.  
  800.           var tree = col.parentNode.parentNode;
  801.           var sib;
  802.           if (col.mTargetCol) {
  803.             // remove previous insertbefore/after attributes
  804.             col.mTargetCol.removeAttribute("insertbefore");
  805.             col.mTargetCol.removeAttribute("insertafter");
  806.             tree.treeBoxObject.invalidateColumn(col.mTargetCol.id);
  807.             sib = col.mTargetCol._previousVisibleColumn;
  808.             if (sib) {
  809.               sib.removeAttribute("insertafter");
  810.               tree.treeBoxObject.invalidateColumn(sib.id);
  811.             }
  812.             col.mTargetCol = null;
  813.             col.mTargetDir = null;
  814.           }
  815.           
  816.           if (targetCol) {
  817.             // set insertbefore/after attributes
  818.             if (pos.value == "after") {
  819.               targetCol.setAttribute("insertafter", "true");
  820.             } else {
  821.               targetCol.setAttribute("insertbefore", "true");
  822.               sib = targetCol._previousVisibleColumn;
  823.               if (sib) {
  824.                 sib.setAttribute("insertafter", "true");
  825.                 tree.treeBoxObject.invalidateColumn(sib.id);
  826.               }
  827.             }
  828.             tree.treeBoxObject.invalidateColumn(targetCol.id);
  829.             col.mTargetCol = targetCol;
  830.             col.mTargetDir = pos.value;
  831.           }
  832.         ]]></body>        
  833.       </method>
  834.  
  835.       <method name="onDragMouseUp">
  836.         <parameter name="aEvent"/>
  837.         <body><![CDATA[
  838.           var col = document.treecolDragging;
  839.           if (!col) return;
  840.           
  841.           if (!col.mDragGesturing) {
  842.             if (col.mTargetCol) {
  843.               // remove insertbefore/after attributes
  844.               var before = col.mTargetCol.hasAttribute("insertbefore");
  845.               col.mTargetCol.removeAttribute(before ? "insertbefore" : "insertafter");
  846.               if (before) {
  847.                 var sib = col.mTargetCol._previousVisibleColumn;
  848.                 if (sib)
  849.                   sib.removeAttribute("insertafter");
  850.               }
  851.                           
  852.               // move the column
  853.               if (col != col.mTargetCol)
  854.                 col.parentNode.parentNode._reorderColumn(col, col.mTargetCol, before);
  855.             
  856.               // repaint to remove lines
  857.               col.parentNode.parentNode.treeBoxObject.invalidate();
  858.   
  859.               col.mTargetCol = null;
  860.             }
  861.           } else
  862.             col.mDragGesturing = false;
  863.                     
  864.           document.treecolDragging = null;
  865.           col.removeAttribute("dragging");
  866.           
  867.           window.removeEventListener("mousemove", col.onDragMouseMove, true);
  868.           window.removeEventListener("mouseup", col.onDragMouseUp, true);
  869.           // we have to wait for the click event to fire before removing
  870.           // cancelling handler
  871.           var clickHandler = function(handler) { 
  872.             window.removeEventListener("click", handler, true);
  873.           };
  874.           window.setTimeout(clickHandler, 0, col.onDragMouseClick);
  875.         ]]></body>        
  876.       </method>
  877.  
  878.       <method name="onDragMouseClick">
  879.         <parameter name="aEvent"/>
  880.         <body><![CDATA[
  881.           // prevent click event from firing after column drag and drop
  882.           aEvent.preventBubble();
  883.           aEvent.preventDefault();
  884.         ]]></body>        
  885.       </method>
  886.     </implementation>
  887.     
  888.     <handlers>
  889.       <handler event="mousedown" button="0"><![CDATA[
  890.         if (this.parentNode.parentNode.enableColumnDrag) {
  891.           var xulns = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
  892.           var cols = this.parentNode.getElementsByTagNameNS(xulns, "treecol");
  893.           
  894.           // only start column drag operation if there are at least 2 visible columns
  895.           var visible = 0;
  896.           for (var i = 0; i < cols.length; ++i)
  897.             if (cols[i].boxObject.width > 0) ++visible;
  898.             
  899.           if (visible > 1) {
  900.             window.addEventListener("mousemove", this.onDragMouseMove, false);
  901.             window.addEventListener("mouseup", this.onDragMouseUp, false);
  902.             document.treecolDragging = this;
  903.             this.mDragGesturing = true;
  904.             this.mStartDragX = event.clientX;
  905.             this.mStartDragY = event.clientY;
  906.           }
  907.         }
  908.       ]]></handler>
  909.     </handlers>
  910.   </binding>
  911.  
  912.   <binding id="treecol" extends="chrome://global/content/bindings/tree.xml#treecol-base">
  913.     <content>
  914.       <xul:label class="treecol-text" xbl:inherits="crop,value=label" flex="1" crop="right"/>
  915.       <xul:image class="treecol-sortdirection" xbl:inherits="sortDirection"/>
  916.     </content>
  917.  
  918.     <handlers>
  919.       <handler event="click" button="0" action="if (event.originalTarget == this) { this.parentNode.parentNode.treeBoxObject.view.cycleHeader(this.id, this); }"/>
  920.     </handlers>
  921.   </binding>
  922.  
  923.   <binding id="treecol-image" extends="chrome://global/content/bindings/tree.xml#treecol-base">
  924.     <content>
  925.       <xul:image class="treecol-icon" xbl:inherits="src"/>
  926.     </content>
  927.     <handlers>
  928.       <handler event="click" button="0" action="this.parentNode.parentNode.treeBoxObject.view.cycleHeader(this.id, this)"/>
  929.     </handlers>
  930.   </binding>
  931.  
  932.   <binding id="columnpicker" display="xul:button"
  933.            extends="chrome://global/content/bindings/tree.xml#tree-base">
  934.     <content>
  935.       <xul:image class="tree-columnpicker-icon"/>
  936.       <xul:menupopup anonid="popup"/>
  937.     </content>
  938.     
  939.     <implementation>
  940.       <method name="buildPopup">
  941.         <parameter name="aPopup"/>
  942.         <body>
  943.           <![CDATA[
  944.             // we no longer cache the picker content.
  945.             // remove the old content
  946.             while (aPopup.hasChildNodes())
  947.               aPopup.removeChild(aPopup.lastChild);
  948.  
  949.             for (var currCol = this.parentNode.firstChild; currCol; currCol = currCol.nextSibling) {
  950.               // Construct an entry for each column in the row, unless
  951.               // it is not being shown
  952.               if (currCol.localName == "treecol" && !currCol.hasAttribute("ignoreincolumnpicker")) {
  953.                 var popupChild = document.createElement("menuitem");
  954.                 popupChild.setAttribute("type", "checkbox");
  955.                 var columnName = currCol.getAttribute("display") || currCol.getAttribute("label");
  956.                 popupChild.setAttribute("label", columnName);
  957.                 popupChild.setAttribute("colid", currCol.id);
  958.                 if (currCol.getAttribute("hidden") != "true")
  959.                   popupChild.setAttribute("checked", "true");
  960.                 if (currCol.getAttribute("primary") == "true")
  961.                   popupChild.setAttribute("disabled", "true");
  962.                 aPopup.appendChild(popupChild);
  963.               }
  964.             }
  965.           ]]>
  966.         </body>
  967.       </method>
  968.     </implementation>
  969.  
  970.     <handlers>
  971.       <handler event="command">
  972.         <![CDATA[
  973.           if (event.originalTarget == this) {
  974.             var popup = document.getAnonymousElementByAttribute(this, "anonid", "popup");
  975.             this.buildPopup(popup);
  976.             popup.showPopup(this, -1, -1, "popup", "bottomright", "topright");
  977.           } else {
  978.             var colid = event.originalTarget.getAttribute("colid");
  979.             var colNode = document.getElementById(colid);
  980.             if (colNode) {
  981.               if (colNode.getAttribute("hidden") == "true")
  982.                 colNode.setAttribute("hidden", "false");
  983.               else
  984.                 colNode.setAttribute("hidden", "true");
  985.             }
  986.           }
  987.         ]]>
  988.       </handler>
  989.     </handlers>
  990.   </binding>
  991. </bindings>
  992.  
  993.